﻿#include "handle_module.h"

Handle_module::Handle_module(QString connect_Name)
{
    common::ConfigureLock.lockForRead();
    bool Log_Open=common::Log_Open;
    Log_Size=common::Log_Size;
    common::ConfigureLock.unlock();
    qRegisterMetaType<task_type>("task_type");
    this->connect_Name=connect_Name;
    isDirExist(QCoreApplication::applicationDirPath()+"\\"+"LOG");
    if(Log_Open)
    {
        connect(&clock,SIGNAL(timeout()),this,SLOT(SaveLog()));
        clock.start(500);
    }
    Savename=QCoreApplication::applicationDirPath()+"\\"+"LOG"+"\\"+"Caculate_Template.log";
    oldname=QCoreApplication::applicationDirPath()+"\\"+"LOG"+"\\"+"Caculate_Template"+".old.log";

}

Handle_module::~Handle_module()
{

}


void Handle_module::handle_init()
{
    c_socket=QSharedPointer<local_socket>(new local_socket(connect_Name));
    connect(c_socket.data(),SIGNAL(reply_data(QString,QString,QString)),this,SLOT(receive_data(QString,QString,QString)));
    c_socket.data()->localSocket_init();
    acquire_serviceType();

}

void  Handle_module::receive_data(QString id, QString type, QString information)
{
    //   qDebug()<<type;
    if(type=="获取服务类型")
    {
        //qDebug()<<information;
        QStringList data=information.split("&");
        QString     s_type;
        QString     thread_Count;
        if(data.size()>=2)
        {
            s_type=data.at(0);
            thread_Count=data.at(1);
        }
        else if(data.size()==1)
        {
            s_type=data.at(0);
        }
        else
        {
            qDebug()<<"获取服务类型错误";
            return;
        }

        if(s_type=="服务器")
        {
            qDebug()<<"当前接入为服务器";
            this->server_type=server;
            caculate_init(1);
            this->c_socket->send_message("计算模块","初始化完成","");
        }
        else if(s_type=="计算节点")
        {
            qDebug()<<"当前接入为计算节点";
            this->server_type=caculate_node;
            bool ok;
            int threadCount=thread_Count.toInt(&ok,10);
            if(ok)
            {
                caculate_init(threadCount);
                QStringList Caculatestatus=getCaculate_status();
                this->c_socket->send_message("计算模块","计算模块状态",Caculatestatus.join("&&&"));
            }
            else
            {
                qDebug()<<"计算节点节点数接受错误！";
                return;
            }
        }
    }
    else  if(type=="read"||type=="handle"||type=="sum")
    {
        QSharedPointer<c_Template> freeTemplate=getFreeTemplate();
        if(!freeTemplate.isNull())
        {
            template_Type[freeTemplate.data()]=caculating_status;
            emit send_instruction(QstringTotype(type),information,freeTemplate.data());
        }
        else
        {
            add_UnhandleTask("",type,information);
        }
    }
    else if(type=="获取程序类型")
    {

        this->c_socket->send_message("计算模块","程序类型","计算模块");
    }
    else  if(type=="计算模块状态")
    {
        QStringList Caculatestatus=getCaculate_status();
        if (Caculatestatus.size()>0)
        {
            this->c_socket->send_message("计算模块",type,Caculatestatus.join("&&&"));
        }
    }
    else
    {
        qDebug()<<"未知type"<<type;
    }
}

void Handle_module::reply_data(task_type type, QString data)
{
    c_Template *c_temolate=qobject_cast<c_Template *>(sender());
    template_Type[c_temolate]=free_status;
    handle_UnhandleTask();
    this->c_socket->send_message("计算模块",typetoQString(type),data);
}

task_type Handle_module::QstringTotype(QString type)
{
    if(type=="read")
    {
        return read;
    }
    else if(type=="handle")
    {
        return handle;
    }
    else if(type=="sum")
    {
        return sum;
    }
    else if(type=="DLL调用失败")
    {
        return loadfail;
    }
    else
    {
        return unknow;
    }
}

QString Handle_module::typetoQString(task_type type)
{
    switch (type) {
    case read:
        return "read";
        break;
    case handle:
        return "handle";
        break;
    case sum:
        return "sum";
        break;
    case loadfail:
        return "DLL调用失败";
        break;
    case readfail:
        return "任务文件解析失败";
        break;
    default:
        return "unknow";
        break;
    }
}


void Handle_module::acquire_serviceType()
{
    c_socket.data()->send_message("计算模块","获取服务类型","");
}

void Handle_module::caculate_init(int threadCount)
{

    for(int a=0;a<threadCount;a++)
    {
        QSharedPointer<c_Template> c_template=QSharedPointer<c_Template>(new c_Template());
        caculate_template[c_template.data()]=c_template;
        template_Type[c_template.data()]=free_status;
        connect(this,SIGNAL(send_instruction(task_type,QString,QObject*)),c_template.data(),SLOT(receive_data(task_type,QString,QObject*)),Qt::QueuedConnection);
        connect(c_template.data(),SIGNAL(send_data(task_type,QString)),this,SLOT(reply_data(task_type,QString)),Qt::QueuedConnection);
        QSharedPointer<QThread>c_thread=QSharedPointer<QThread>(new QThread());
        thread[c_template.data()]=c_thread;
        c_template.data()->moveToThread(c_thread.data());
        c_thread.data()->start();
    }
}

QSharedPointer<c_Template> Handle_module::getFreeTemplate()
{

    QSharedPointer<c_Template> c_template;
    QMap<c_Template*,caculate_status>::const_iterator i;
    for (i = template_Type.constBegin(); i != template_Type.constEnd(); ++i) {    //对QMAP进行遍历
            if(i.value()==free_status)
            {
                c_template=caculate_template[i.key()];
                break;
            }
    }
    if(c_template.isNull())
    {
   //     qDebug()<<"当前没有空闲计算模块!";
    }
    return c_template;
}

QStringList Handle_module::getCaculate_status()
{
    QStringList result;
    QMap<c_Template*,caculate_status>::const_iterator i;
    for (i = template_Type.constBegin(); i != template_Type.constEnd(); ++i) {    //对QMAP进行遍历
        if(i.value()==free_status)
        {
            result.append("空闲");
        }
        else if(i.value()==caculating_status)
        {
            result.append("忙碌");
        }
    }
    return result;
}

void Handle_module::add_UnhandleTask(QString id, QString type, QString data)
{
    UnHandleTask Task={id,type,data};
    UnHandleTaskList.append(Task);
}

void Handle_module::handle_UnhandleTask()
{
    if(UnHandleTaskList.isEmpty())
    {
        return;
    }

    QSharedPointer<c_Template> freeTemplate=getFreeTemplate();
    if(!freeTemplate.isNull())
    {
        template_Type[freeTemplate.data()]=caculating_status;
        UnHandleTask Task= UnHandleTaskList.first();
        emit send_instruction(QstringTotype(Task.type),Task.data,freeTemplate.data());
        UnHandleTaskList.removeFirst();
        handle_UnhandleTask();
    }

}

bool Handle_module::isDirExist(QString fullPath)
{
    QDir dir(fullPath);
    if(dir.exists())
    {
        return true;
    }
    else
    {
        bool ok = dir.mkdir(fullPath);//只创建一级子目录，即必须保证上级目录存在
        return ok;
    }
}

void Handle_module::SaveLog()
{

    QStringList logdata;
    common::LogdataLock.lockForWrite();
    logdata=common::Logdata;
    common::Logdata.clear();
    common::LogdataLock.unlock();
    QFile outputFile(Savename);
    outputFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text);
    QTextStream textStream(&outputFile);
    for(int a=0;a<logdata.size();a++)
    {
        textStream << logdata[a] << endl;
    }
    outputFile.flush();
    outputFile.close();
    QFileInfo fileinfor(outputFile);

    // qDebug()<<fileinfor.size()<<fileinfor.size()/(MB)<<Log_Size;
    if(fileinfor.size()/(MB)>Log_Size)
    {
        QFile deletelog(oldname);
        deletelog.remove();
        qDebug()<<outputFile.rename(Savename,oldname);
    }


}
